package com.neutech.maplestory.entity;

import com.neutech.maplestory.client.MapleStoryClient;
import com.neutech.maplestory.constant.Constant;
import com.neutech.maplestory.util.ImageUtil;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;


import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Random;

public class Hero extends AbstractMapleStoryObject {
    public static Image[] imgs = new Image[100];

    static {
        for (int i = 0; i < 4; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_stand" + i);
        }
        for (int i = 4; i < 8; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_stand" + (i - 4));
        }
        for (int i = 8; i < 13; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_walk" + (i - 8));
        }
        for (int i = 13; i < 18; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_walk" + (i - 13));
        }
        imgs[18] = ImageUtil.getImage("hero_right_prone");
        imgs[19] = ImageUtil.getImage("hero_left_prone");
        imgs[20] = ImageUtil.getImage("hero_right_jump");
        imgs[21] = ImageUtil.getImage("hero_left_jump");


        for (int i = 22; i < 26; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_shoot" + (i - 22));
        }
        for (int i = 26; i < 30; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_shoot" + (i - 26));
        }

    }

    public MapleStoryClient msc;


    public Hero() {
    }

    /**
     * 人物血量上限
     */
    public int MAX_HP = 1000;
    public int HP;
    public int MP;
    public int MAX_MP = 1000;
    public int EXP;
    public int MAX_EXP = 200;

    /**
     * 人物的基础攻击力
     */
    public int ATT;
    public int hitValue;
    public Random random = new Random();


    public Hero(MapleStoryClient msc, int x, int y) {
        this.msc = msc;
        this.x = x;
        this.y = y;
        this.MP = 1000;
        this.HP = 1000;
        this.EXP = 0;
        this.ATT = 1000;

        this.speed = Constant.HERO_SPEED;
        this.width = imgs[0].getWidth(null);
        this.height = imgs[0].getHeight(null);
        this.dir = Direction.RIGHT;
        this.action = Action.STAND;

    }

    /**
     * 一直加的计数器
     */
    public int count = 0;
    /**
     * 计算当前画第几张图
     */
    private int step = 0;
    /**
     * 左右的开关
     */
    public boolean left, right, down, jump, shoot, pickup,moveup;

    @Override
    public void draw(Graphics g) {
        switch (dir) {
            case LEFT:
                switch (action) {
                    case STAND:
                        //left stand
                        if (count++ % 5 == 0) {
                            g.drawImage(imgs[(step++ % 4) + 4], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 4 + 4], x, y, null);
                        }
                        break;
                    case WALK:
                        //left walk
                        if (count++ % 5 == 0) {
                            g.drawImage(imgs[(step++ % 5) + 13], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 5 + 13], x, y, null);
                        }
                        break;
                    case PRONE:
                        g.drawImage(imgs[19], x, y + 30, null);
                        break;
                    case JUMP:
                        g.drawImage(imgs[21], x, y + 35, null);
                        break;
                    case SHOOT:
                        //left shoot
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step++ % 4) + 26], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 4 + 26], x, y, null);
                        }
                        break;
                    case UP:
                        g.drawImage(imgs[21], x, y, null);
                        break;
                    default:
                        break;
                }

                break;
            case RIGHT:
                switch (action) {
                    case STAND:
                        //right stand
                        if (count++ % 5 == 0) {
                            g.drawImage(imgs[step++ % 4], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 4], x, y, null);
                        }
                        break;
                    case WALK:
                        //right stand
                        if (count++ % 5 == 0) {
                            g.drawImage(imgs[(step++ % 5) + 8], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 5 + 8], x, y, null);
                        }
                        break;
                    case PRONE:
                        g.drawImage(imgs[18], x, y + 30, null);
                        break;
                    case JUMP:
                        g.drawImage(imgs[20], x, y + 35, null);
                        break;
                    case SHOOT:
                        //right shoot
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step++ % 4) + 22], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 4 + 22], x, y, null);
                        }
                        break;
                    case UP:
                        g.drawImage(imgs[20], x, y, null);
                        break;
                    default:
                        break;
                }
                break;

            default:
                break;
        }

        move();
        magicBar.draw(g);
        bloodBar.draw(g);
        expBar.draw(g);
        hurt(msc.mobs);
    }

    @Override
    public void move() {
        if (left) {
            x -= speed;
            this.action = Action.WALK;
        }
        if (right) {
            x += speed;
            this.action = Action.WALK;
        }
        if (moveup && !left && !right) {
            y -= speed;
            this.action = Action.UP;
        }else{
            moveup = false;
        }
        if (jump) {
            jump(msc.grounds);
        } else if (moveup && !left && !right) {
        }else{   //自由落体
            jumpDown(msc.grounds);

        }
        if (shoot) {
            shoot();
        }
        if (pickup) {
            pickup(msc.items);
        }

        confirmDirection();
        outOfBound();
    }

    /**
     * 射击持续时长的变量
     */
    private int shootCount = 0;

    /**
     * 射击的方法
     */
    private void shoot() {
        shootCount++;

        if (shootCount % 10 == 0) {

            shoot = false;
            this.MP -= 5;
            Arrow arrow;
            if (dir == Direction.RIGHT) {
                arrow = new Arrow(msc, x + this.width, y + height / 2 + 8, dir);
            } else {
                arrow = new Arrow(msc, x, y + height / 2 + 8, dir);
            }
            msc.arrows.add(arrow);
        }

    }

    private double v0 = Constant.HERO_INIT_JUMP_SPEED;
    private double vt;
    private double g = 9.8;
    private double delta_height;
    private double t = 0.7;

    /**
     * 跳跃的方法
     */
    public void jump(List<Ground> grounds) {
        if (!drop) {
            //竖直上抛
            vt = v0 - g * t;
            delta_height = v0 * t;
            v0 = vt;
            y -= delta_height;
            //什么时候往下跳
            if (vt <= 0) {
                vt = 0;
                drop = true;
            }
        } else {
            jumpDown(grounds);
        }
    }

    private boolean drop = true;

    public void jumpDown(List<Ground> grounds) {
        //掉的过程
        vt = v0 + g * t;
        delta_height = v0 * t;
        v0 = vt;
        y += delta_height;
        //什么时候停止自由落体
        for (int i = 0; i < grounds.size(); i++) {
            Ground ground = grounds.get(i);
            if (this.getRectangle().intersects(ground.getRectangle()) &&
                    this.y <= ground.y - this.height + 80) {
                //跳
                if (this.y >= ground.y - this.height) {
                    this.y = ground.y - this.height;
                    drop = false;
                    jump = false;
                    v0 = Constant.HERO_INIT_JUMP_SPEED;
                    vt = 0.0;
                    break;
                }
            } else {
                drop = true;
            }

        }
    }
    /*private void jump() {
        //vt=v0+gt    竖直上抛
        vt = v0 - g * t;
        delta_height = v0 * t;
        v0 =vt;
        y -= delta_height;
        //自由落体的结束位置
        if(y>=500){
            jump = false;
            v0 = Constant.HERO_INIT_JUMP_SPEED;
            vt=0.0;
            y = 500;
        }
    }*/
    /**
     * 人物和怪物的碰撞减血
     */
    private int time = 0;
    private boolean d = true;
    public void hurt(List<Mob> mobs) {
        for (int i = 0; i < mobs.size(); i++) {
            Mob a = mobs.get(i);
            if (this.getRectangle().intersects(a.getRectangle()) && d == true) {
                this.HP -= 10;
                d = false;
            }
        }
        switch (time){
            case 80:
                d = true;
                time = 0;
                break;
            default:
                time++;
                break;
        }
    }

    /**
     * 根据当前人物的左右开关，确定人物的方向
     */
    private void confirmDirection() {
        if (left && !right) {
            this.dir = Direction.LEFT;
            if (jump) {
                this.action = Action.JUMP;
            }
        } else if (right && !left) {
            this.dir = Direction.RIGHT;
            if (jump) {
                this.action = Action.JUMP;
            }
        } else if (jump) {
            this.action = Action.JUMP;
        } else if (down) {
            this.action = Action.PRONE;
        } else if (shoot) {
            this.action = Action.SHOOT;
        }else if(moveup) {
            this.action = Action.UP;
        } else {
            this.action = Action.STAND;
        }
        //都按下或者都不按下

    }

    /**
     * 按键的方法
     *
     * @param e 键盘事件对象
     */
    public Ground stack = new Ground(this.msc,750,304,30,150);
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_A:
                left = true;
                break;
           case KeyEvent.VK_W:
               if(this.getRectangle().intersects(stack.getRectangle())){
                   moveup = true;
                   drop = false;
               }else{
                   moveup = false;
                   drop = true;
               }
                break;
  /*          case KeyEvent.VK_S:
                y += speed;
                break;               */
            case KeyEvent.VK_D:
                right = true;
                break;
            case KeyEvent.VK_S:
                down = true;
                break;
            case KeyEvent.VK_K://跳跃
                jump = true;
                break;
            case KeyEvent.VK_J://攻击
                shoot = true;
                break;
            case KeyEvent.VK_L: //捡道具
                pickup = true;
                break;


            default:
                break;
        }
    }

    /**
     * 释放按键的方法
     *
     * @param e 键盘事件
     */

    public void keyReleased(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_A:
                left = false;
                break;
            case KeyEvent.VK_W:
                moveup = false;
                break;
            case KeyEvent.VK_D:
                right = false;
                break;
   /*         case KeyEvent.VK_S:
                break;*/
            case KeyEvent.VK_S:
                down = false;
                break;
    /*        case KeyEvent.VK_J:
                shoot = false ;
                break;*/
            case KeyEvent.VK_L: //捡道具
                pickup = false;
                break;
            default:
                break;
        }
    }

    /**
     * 边界判断问题
     */
    private void outOfBound() {
        if(this.y<=0){
            this.y=0;
        }
        if (this.x <= 0) {
            this.x = 0;
        }
        if (this.x >= Constant.GAME_WIDTH - this.width) {
            this.x = Constant.GAME_WIDTH - this.width;
        }
        if (this.dir == Direction.RIGHT) {
            if (this.x >= 470 - this.width && this.y >= 420 - this.height + 40 && this.x <=700-this.width) {
                this.x = 470 - this.width;
            }
     /*      if (this.x>=650-this.width&& this.y>=460-this.height +40 && this.x<=900-this.width){
                this.x=650-this.width;
            }*/
        }
        if (this.dir == Direction.LEFT) {
            if (this.x <= 700 && this.y >= 420 - this.height + 40 && this.x>=470-this.width) {
                this.x = 700;
            }
        }
    }

    /**
     * 捡道具
     *
     * @param item 道具对象
     * @return 是否捡到
     */
    private boolean pickup(Item item) {
        if (item.live && this.getRectangle().intersects(item.getRectangle())) {
            item.live = false;
            //存放之前和道具包里面的没一个进行判断
            for (int i = 0; i < msc.itemPackage.items.size(); i++) {
                Item itm = msc.itemPackage.items.get(i);
                //如果相同，数量+1
                if (item.type == itm.type) {
                    itm.qty += 1;
                    return false;

                }
            }
            //业务   放入道具包
            msc.itemPackage.items.add(item);




         /*   switch (item.type){
                case 0:
                    this.HP+=50;
                    break;
                case 1:
                    this.HP+=100;
                    break;
                case 2:
                    this.HP+=300;
                    break;
                case 3:
                    this.MP+=100;
                    break;
                default:
                    break;
            }
            if ((HP>=MAX_HP)){
                HP=MAX_HP;
            }
            if ((MP>=MAX_MP)){
                MP=MAX_MP;
            }*/


        }
        return false;

    }

    /**
     * 捡一堆道具
     *
     * @param items 道具容器
     * @return 是否捡起来
     */
    public boolean pickup(List<Item> items) {
        for (int i = 0; i < items.size(); i++) {
            Item item = items.get(i);
            if ((pickup(item))) {
                return true;
            }
        }
        return false;
    }
    public Hero.BloodBar bloodBar = new Hero.BloodBar();
    class BloodBar extends AbstractMapleStoryObject {
        private Image img;

        public BloodBar() {
            this.img = ImageUtil.getImage("0");
            this.width = img.getWidth(null);
        }

        @Override
        public void draw(Graphics g) {
            int n = 75 / this.width * Hero.this.HP / Hero.this.MAX_HP;
            for (int i = 0; i < (75 / this.width) -n; i++) {
                g.drawImage(img, 672 - (i * this.width +1), 716 , null);//加图片
            }
        }

    }
    public MagicBar magicBar = new MagicBar();
    class MagicBar extends AbstractMapleStoryObject{
        private Image img;
        public MagicBar(){
            this.img = ImageUtil.getImage("0");
            this.width = img.getWidth(null);
        }
        @Override
        public void draw(Graphics g) {
            int n = 75 / this.width * Hero.this.MP / Hero.this.MAX_MP;
            for (int i = 0; i < (75 / this.width) -n; i++) {
                g.drawImage(img, 747 - (i * this.width +1), 716 , null);
            }

        }
    }
    public EXPBar expBar = new EXPBar();
    class EXPBar extends AbstractMapleStoryObject{
        private Image img;
        public EXPBar(){
            this.img = ImageUtil.getImage("0");
            this.width = img.getWidth(null);
        }
        @Override
        public void draw(Graphics g) {
            int n = 80 / this.width * Hero.this.EXP / Hero.this.MAX_EXP;
            for (int i = 0; i < (80 / this.width) -n; i++) {
                g.drawImage(img, 830 - (i * this.width +1), 716 , null);
            }

        }
    }
}
